package com.dman.multi.ui.comp;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.util.List;

import org.apache.pivot.wtk.Component;
import org.apache.pivot.wtk.Dimensions;
import org.apache.pivot.wtk.GraphicsUtilities;
import org.apache.pivot.wtk.Orientation;
import org.apache.pivot.wtk.Theme;
import org.apache.pivot.wtk.skin.ComponentSkin;
import org.apache.pivot.wtk.skin.terra.TerraTheme;


/**
 * Meter skin.
 */
public class TerraPiecewiseMeterSkin extends ComponentSkin
    implements PiecewiseMeterListener {
    private Color fillColor;
    private Color gridColor;

    private static final int DEFAULT_WIDTH = 100;
    private static final int DEFAULT_HEIGHT = 25;

    public TerraPiecewiseMeterSkin() {
        TerraTheme theme = (TerraTheme)Theme.getTheme();
        fillColor = theme.getColor(16);
        gridColor = theme.getColor(10);
    }

    @Override
    public void install(Component component) {
        super.install(component);

        PiecewiseMeter meter = (PiecewiseMeter)component;
        meter.getPiecewiseMeterListeners().add(this);
    }

    @Override
    public boolean isFocusable() {
        return false;
    }

    @Override
    public int getPreferredWidth(int height) {
        PiecewiseMeter meter = (PiecewiseMeter)getComponent();

        int preferredWidth = DEFAULT_WIDTH;
        if (meter.getOrientation() == Orientation.VERTICAL) {
            preferredWidth = getPreferredHeight(-1);
        }

        return preferredWidth;
    }

    @Override
    public int getPreferredHeight(int width) {
        PiecewiseMeter meter = (PiecewiseMeter)getComponent();

        int preferredHeight = DEFAULT_HEIGHT;
        if (meter.getOrientation() == Orientation.VERTICAL) {
            preferredHeight = getPreferredWidth(width);
        }

        return preferredHeight;
    }

    @Override
    public Dimensions getPreferredSize() {
    	PiecewiseMeter meter = (PiecewiseMeter)getComponent();

        int preferredWidth = DEFAULT_WIDTH;
        int preferredHeight = DEFAULT_HEIGHT;
        
        Dimensions preferredSize;
        if (meter.getOrientation() == Orientation.HORIZONTAL) {
            preferredSize = new Dimensions(preferredWidth, preferredHeight);
        } else {
            preferredSize = new Dimensions(preferredHeight, preferredWidth);
        }

        return preferredSize;
    }

    @Override
    public int getBaseline(int width, int height) {
        int baseline = -1;
        return baseline;
    }

    @Override
    public void layout() {
        // No-op
    }

    @Override
    public void paint(Graphics2D graphics) {
    	PiecewiseMeter meter = (PiecewiseMeter)getComponent();

        int width = getWidth();
        int height = getHeight();

        if (meter.getOrientation() == Orientation.HORIZONTAL) {
            drawMeter(meter, graphics, width, height);
        } else {
            graphics.rotate(-Math.PI / 2d);
            graphics.translate(-height, 0);
            drawMeter(meter, graphics, height, width);
        }
    }

    private void drawMeter(PiecewiseMeter meter, Graphics2D graphics, int width, int height) {
        
        // Paint the interior fill
        graphics.setPaint(new GradientPaint(0, 0, TerraTheme.brighten(fillColor),
            0, height, TerraTheme.darken(fillColor)));
        
        // loop through the range and fill rectangle
        List<Range> lRange = meter.getListOfRanges();
        int listLen = lRange.size();
        long size = lRange.get(listLen - 1).getEnd() + 1;
        
        // compute the piece length and amount of progress within a piece
        int pieceLength = 0;
        int meterStop = 0;
        int xorigin = 0;
        int yorigin = 0;
        for(Range range: lRange){
        	pieceLength = (int) (range.getEnd() - range.getStart() + 1);
        	meterStop = (int) (range.getLength() * width / size);
        	graphics.fillRect(xorigin, yorigin, meterStop, height);
        	if(meter.getOrientation() == Orientation.HORIZONTAL){
        		xorigin += (int) (pieceLength * width / size);
        	} else {
        		yorigin += (int) (pieceLength * width / size);
        	}
        }

        // Paint the grid
        graphics.setPaint(gridColor);
        GraphicsUtilities.drawRect(graphics, 0, 0, width, height);
    }

    public Color getColor() {
        return fillColor;
    }

    public void setColor(Color color) {
        this.fillColor = color;
        repaintComponent();
    }

    public final void setColor(String color) {
        if (color == null) {
            throw new IllegalArgumentException("color is null.");
        }

        setColor(GraphicsUtilities.decodeColor(color));
    }

    public Color getGridColor() {
        return gridColor;
    }

    public void setGridColor(Color gridColor) {
        this.gridColor = gridColor;
        repaintComponent();
    }

    public final void setGridColor(String gridColor) {
        if (gridColor == null) {
            throw new IllegalArgumentException("gridColor is null.");
        }

        setGridColor(GraphicsUtilities.decodeColor(gridColor));
    }
    /**
     * Listener for meter percentage changes.
     *
     * @param meter
     *     The source of the event.
     *
     * @param previousPercentage
     *     The previous percentage value.
     */
	@Override
	public void sectionPercentagesChanged(PiecewiseMeter meter,
			List<Range> rangeList) {
		repaintComponent();
	}

    /**
     * Listener for meter orientation changes.
     *
     * @param meter
     *     The source of the event.
     */
    @Override
	public void orientationChanged(PiecewiseMeter meter) {
		invalidateComponent();
	}

}
